﻿package ru.vega_int.firsoff.as3
{
	import flash.display.Shape;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.errors.IllegalOperationError;
	import flash.events.*;
	import flash.geom.ColorTransform;
	import flash.system.System;
	import flash.ui.Keyboard;
	import flash.text.*;
	/**
	 * Обычный логгер, для удаленного просмотра событий приложения
	 *
	 * @author firsoff maxim, email: firsoff_maxim@mail.ru, icq:235859730, tel:+79222345364
	 * @version 0.0.1 / 30.12.2007 0:15
	 */
	
	public class Logger extends Sprite
	{
		//	PROPERTIES
		//	private
		private static var _instance:Logger;		//	экземпляр
		private var _header:Sprite;				//	заголовок
		private var _background:Sprite;			//	фон
		private var _labelField:TextField;		//	текст заголовка
		private var _logField:TextField;		//	текстовое поле лога
		private var _log:Array;					//	лог
		private var _stage:Stage;				//	ссылка на сцену
		private var _label:String = 'please, put your data here =)';				//	заголовок
		private var _headerFormat:TextFormat;	//	формат заголовка
		private var _logFormat:TextFormat;		//	формат лога
		private var _isShow:Boolean;				//	показывается ли сейчас?
		
		private const _headerBgdColor:uint = 0xCCCCCC;		//	цвет фона заголовка
		private const _headerColor:uint = 0x003300;			//	цвет текста
		private const fontSizeHeader:uint = 12;				//	размер шрифта
		
		private var _backgroundColor:uint = 0xFFFFFF;	//	цвет фона тела
		private const _logColor:uint = 0x000000;			//	цвет текста
		private const fontSizeLog:uint = 12;				//	размер шрифта
		
		private const _WIDTH:Number = 500;
		private const _HEIGHT:Number = 300;
		private const _HEADER_HEIGHT:Number = 20;
		
		private var _posX:Number;		//	переменные для сохранения последнего положения
		private var _posY:Number;
		//private const DEFAULT_LABEL:String = 'please, put your data here =)';
		//private const DEFAULT_HOT_KEY
		//	public
		public static var enable:Boolean = true;
		//	-------------------------------------------------------------
		//	CONSTRUCTOR
		public function Logger(s:Stage, label:String=null):void
		{
			if(!_instance)
			{
				if(label){_label = label;};
				_stage = s;
				init();
			}
			else{throw new IllegalOperationError('Logger already exists');};
		};
		
		
		//	METHODS
		//	private
		private function init():void
		{
			if (enable)
			{
				_instance = this;
				_isShow = false;
				
				_log = new Array();
				_stage.addEventListener(KeyboardEvent.KEY_DOWN, handlerKeyDown);
				
				_headerFormat = new TextFormat();
				_headerFormat.size = fontSizeHeader;
				_headerFormat.font = '_sans, Arial';
				_headerFormat.color = _headerColor;
				
				_logFormat = new TextFormat();
				_logFormat.size = fontSizeLog;
				_logFormat.font = '_sans, Arial';
				_logFormat.color = _logColor;
				
				createHeader();
				createBody();
			};
		};
		
		private function createHeader():void
		{
			_header = new Sprite();
			//	заголовок
			_labelField = new TextField();
			_labelField.autoSize = TextFieldAutoSize.LEFT;
			_labelField.selectable = false;
			_labelField.mouseEnabled = false;
			_labelField.text = _label;
			_labelField.setTextFormat(_headerFormat);
			_labelField.x = 10;
			_header.addChild(_labelField);
			addChild(_header);
			
			// фон
			_header.graphics.beginFill(_headerBgdColor, 1);
			_header.graphics.drawRect(0, 0, _WIDTH, _HEADER_HEIGHT);
			_header.graphics.endFill();
			
			// кнопка CLOSE
			var close:Sprite = new Sprite();
			var rad:Number = _HEADER_HEIGHT/2 * 0.7;
			close.graphics.beginFill(0xFF0000, 1);
			close.graphics.drawCircle(rad,rad,rad);
			close.x = _WIDTH - _HEADER_HEIGHT;
			close.y = (_HEADER_HEIGHT - close.height)/2;
			close.useHandCursor = close.buttonMode = true;
			close.addEventListener(MouseEvent.CLICK, handleClose);
			_header.addChild(close);
			
			_header.addEventListener(MouseEvent.MOUSE_DOWN, handleHeaderMouseDown);
			_header.addEventListener(MouseEvent.MOUSE_UP, handleHeaderMouseUp);
			_header.addEventListener(MouseEvent.MOUSE_MOVE, handleHeaderMouseMove);
		};
		
		
		private function createBody():void
		{
			_background = new Sprite();
			//	заливка
			_background.y = _HEADER_HEIGHT;
			_background.graphics.beginFill(_backgroundColor, 1);
			_background.graphics.drawRect(0, 0, _WIDTH, _HEIGHT);
			_background.graphics.endFill();
			
			//	текстовое поле
			_logField  = new TextField();
			_logField.width = _WIDTH - 20;
			_logField.height = _HEIGHT - 20;
			_logField.wordWrap = true;
			
			_logField.x = 10;
			_logField.y = 10;
			_background.addChild(_logField);
			addChild(_background);
		};
		private function align():void
		{
			if(!_posX)
			{
				this.x = Math.round((_stage.stageWidth - this.width)/2);
				this.y = Math.round((_stage.stageHeight - this.height)/2);
			};
		};
		
		private function makeLog():String
		{
			var out:String='';
			for (var i:int = 0; i <_log.length ; i++) 
			{
				out += (i + 1) +  '. ' + _log[i] + '\n';
			};
			return out;
		};
		private function updateText() :void
		{
			_logField.text = makeLog();
			_logField.setTextFormat(_logFormat);
			_logField.scrollV = _logField.maxScrollV;
		};
				//	public
		public function addMessage(mess:*):void
		{
			if (enable)
			{
				_log.push(mess);
				updateText();
			};
		};
		
		public static function clearLog():void
		{
			//_logField.text = '';
		};
		
		public function getMessageAt(position:uint) :String
		{
			if(position > _log.length){throw new IllegalOperationError('position error');}
			else {return String(_log[position]);};
		};
		
		public function setBackgroundColor(c:uint):void
		{
			if (enable)
			{
				_backgroundColor = c;
				_background.graphics.clear();
				_background.graphics.beginFill(_backgroundColor, 1);
				_background.graphics.drawRect(0, 0, _WIDTH, _HEIGHT);
				_background.graphics.endFill();
			}
		};
		//	-------------------------------------------------------------
		
		//	GETTERS/SETTERS
		//	-------------------------------------------------------------
		
		//	HANDLERS
		private function handlerKeyDown(event:KeyboardEvent) :void
		{
			if(event.shiftKey && event.keyCode == 53)
			{
				_isShow = !_isShow;
				if(_isShow)
				{
					//_stage.focus = this._labelField;
					updateText();
					align();
					_stage.addChild(this);
					
					
				}
				else
				{
					_posX = this.x;
					_posY = this.y;
					_stage.removeChild(this);
					_logField.text = '';
				}
				// скидываем в буфер заголовок логгера
				System.setClipboard(_label);
			};
			
		};
		
		private function handleClose(e:Event):void
		{
			_isShow = false;
			_posX = this.x;
			_posY = this.y;
			_stage.removeChild(this);
			_stage.focus = _stage;
			this.stopDrag();
		};
		
		private function handleHeaderMouseDown(e:MouseEvent) :void
		{
			this.startDrag();
		};
		
		private function handleHeaderMouseUp(e:MouseEvent) :void
		{
			this.stopDrag();
		};
		
		private function handleHeaderMouseMove(e:MouseEvent) :void
		{
			e.updateAfterEvent();
		};
		//	-------------------------------------------------------------
	};
};